﻿using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace RabbitMQDemo
{
    public partial class RpcServer : Form
    {
        private readonly static RpcServer _RpcServer;
        Action<string, TextBox> SetText;
        static RpcServer()
        {
            _RpcServer = new RpcServer();
        }
        /// <summary>
        /// 单例模式
        /// </summary>
        public static RpcServer SingleForm { get { return _RpcServer; } }
        private RpcServer()
        {
            CheckForIllegalCrossThreadCalls = false;
            InitializeComponent();
            ReceiveMsg(txtRpcServer);//服务端
            SetText += OnSetText;
        }

        /// <summary>
        /// 服务端接收消息
        /// </summary>
        private void ReceiveMsg(TextBox box)
        {
            try
            {
                var factory = new ConnectionFactory() { HostName = "localhost" };
                var connection = factory.CreateConnection();
                var channel = connection.CreateModel();

                //声明队列
                channel.QueueDeclare(queue: "rpc_queue",
                    durable: false,
                    exclusive: false,
                    autoDelete: false,
                    arguments: null);

                //每个消费者最多消费一条消息,没返回消息确认之前不再接收消息
                channel.BasicQos(0, 1, false);

                var consumer = new EventingBasicConsumer(channel);

                consumer.Received += (model, ea) =>
                {
                    string response = null;
                    var body = ea.Body;
                    var props = ea.BasicProperties;
                    var replyProps = channel.CreateBasicProperties();
                    replyProps.CorrelationId = props.CorrelationId;
                    var msg = Encoding.UTF8.GetString(body);
                    //服务端显示内容
                    box.Invoke(SetText, msg, box);
                    response = "我将给你回复：已收到消息-" + msg;

                    var responseBytes = Encoding.UTF8.GetBytes(response);
                    channel.BasicPublish(exchange: "",
                        routingKey: props.ReplyTo,
                        basicProperties: replyProps,
                        body: responseBytes);
                    //手动向rabbitmq发送消息确认
                    channel.BasicAck(deliveryTag: ea.DeliveryTag,
                        multiple: false);
                };
                channel.BasicConsume(queue: "rpc_queue",
                    noAck: false,//手动确认消息
                    consumer: consumer);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        private void OnSetText(string text, TextBox box)
        {
            box.Text += string.Format("{0}\r\n", text);
        }
    }
}
